package main

import(
	//"github.com/gorilla/sessions"
	"questionnaire-gen/backend"
	"fmt"
//	"log"
//	"encoding/json"
	"net/http"
	"gopkg.in/mgo.v2"
	"github.com/gorilla/sessions"
)

type AppContext struct{
	MongoSession *mgo.Session
	store *sessions.CookieStore
	//hard coded values passed at application startup
	AdminName, AdminEmail, AdminPassword string
}

type ReqContext struct {
	CurrentUser *backend.User
	Payload map[string]interface{}
}


type AppHandler struct{
	Context *AppContext
	httpFunc httpFunc // actual wrapped function
	Handler http.Handler
	auth, jsonReq, jsonRes bool
}


//type httpFunc func(w http.ResponseWriter, r *http.Request)
type httpFunc func( w http.ResponseWriter, r *http.Request, c *AppContext, rc *ReqContext) error 


func myHandler(handler http.Handler) *AppHandler{
	my := &AppHandler{Handler: handler}
	return my
}

func myHandlerFunc(f httpFunc) *AppHandler{
	my := &AppHandler{httpFunc: f}
	return my
}

func (my *AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request){
	var rc *ReqContext = new(ReqContext)

	if my.auth {
		s, _ := store.Get(r, "user")
		name, ok := s.Values["id"]
		if !ok { // name not found, user not authenticated, must login first
			fmt.Printf("User not authenticated, must login first")
			fmt.Fprint(w, "User not authenticated, must login first")
			return;
		}
		fmt.Printf("User authenticated with name : %s \n", name)
	}

	if my.httpFunc != nil {
		my.httpFunc(w, r, ApplicationContext, rc)
		return
	}

	my.Handler.ServeHTTP(w, r) 
}



//Check request is authenticated 
func (my *AppHandler) Auth() *AppHandler{
	my.auth = true
	return my
}
//Parse r.Body as JSON
func (my *AppHandler) JsonReq() *AppHandler{
	my.jsonReq = true
	return my
}

func (my *AppHandler) JsonRes() *AppHandler{
	my.jsonReq = true
	return my
}

//func testAuth(w http.ResponseWriter, r *http.Request){
func testAuth(w http.ResponseWriter, r *http.Request, c *AppContext, rc *ReqContext) error{
	fmt.Fprint(w, "authentication passed")
	return nil
}


type AppRequest struct{
	*http.Request
	Payload map[string]*interface{}
}

func (r *AppRequest) AddPayload(name string, item *interface{}){
	r.Payload[name] = item
}




